import json
import math
import os
from pydoc import pager
import requests
import time

# 图标：https://static-data.gaokao.cn/upload/logo/1159.jpg
# 爬取网站：https://www.gaokao.cn/school/1159

# 省
province_id = 42

# 请求头
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36',
    'Origin': 'https://gkcx.eol.cn',
    'Referer': 'https://gkcx.eol.cn/hotschool?province=%E6%B9%96%E5%8C%97',
}


# 学科类型
# 测试：https://static-data.gaokao.cn/www/2.0/config/dicprovince/dic.json
# 1: 理科 2: 文科  10: 专科批
def get_professional():
    path = "学科类型.json"
    # 判断文件是否存在
    if os.path.exists(path) == True:
        return read_json(path)
    url = "https://static-data.gaokao.cn/www/2.0/config/dicprovince/dic.json"
    try:
        response = requests.get(url=url, headers=headers)
    except Exception as gk:
        print(gk)
        # 防反爬虫，停3秒再试
        time.sleep(3)
        response = requests.get(url=url, headers=headers)
    data = json.loads(response.text)['data']['item']
    save_json(path, data)
    print(data)


# 关键字查询指定学校
# 测试：https://api.eol.cn/web/api/?keyword=大学名称&page=1&size=20&sort=view_total&uri=apidata/api/gk/school/lists
def get_keyword_school(name):
    url = "https://api.eol.cn/web/api/?keyword=" + name + \
        "&page=1&size=20&sort=view_total&uri=apidata/api/gk/school/lists"
    try:
        response = requests.get(url=url, headers=headers)
    except Exception as gk:
        print(gk)
        # 防反爬虫，停3秒再试
        time.sleep(3)
        response = requests.get(url=url, headers=headers)
    data = json.loads(response.text)['data']['item']
    info = {
        'name': data[0]['name'],
        'school_id': data[0]['school_id'],
        # 'address': data[0]['address'],
        'type_name': data[0]['type_name'],
        'level_name': data[0]['level_name'],
        'nature_name': data[0]['nature_name'],
        'province_name': data[0]['province_name'],
        'city_name': data[0]['city_name'],
    }
    print("学校: " + name + " 查询成功！")
    path = str(info['school_id']) + "_" + name + "_学校信息.json"
    save_json(path, info)
    return info


# 根据id查询学校信息
# 测试：https://static-data.gaokao.cn/www/2.0/school/428/info.json
def get_id_school(id):
    url = "https://static-data.gaokao.cn/www/2.0/school/" + \
        str(id) + "/info.json"
    try:
        response = requests.get(url=url, headers=headers)
    except Exception as gk:
        print(gk)
        # 防反爬虫，停3秒再试
        time.sleep(3)
        response = requests.get(url=url, headers=headers)
    data = json.loads(response.text)['data']
    info = {
        'name': data['name'],
        'school_id': data['school_id'],
        'address': data['address'],
        'type_name': data['type_name'],
        'level_name': data['level_name'],
        'nature_name': data['nature_name'],
        'province_name': data['province_name'],
        'city_name': data['city_name'],
    }
    print("学校id: " + str(id) + " 查询成功！")
    path = str(id) + "_" + info['name'] + "_学校信息.json"
    save_json(path, info)
    return info


# 根据关键字查询专业id
# 测试：https://api.eol.cn/web/api/?keyword=%E5%AD%A6%E5%89%8D%E6%95%99%E8%82%B2&level1=2&level2=&page=1&size=30&sort=&uri=apidata/api/gkv3/special/lists
def get_keyword_special_id(keyword):
    url = "https://api.eol.cn/web/api/"
    url_data = {
        'keyword': keyword,  # 专业名称
        'level1': 1,  # 学校级别 1 本科 2 专科
        'level2': "",
        'page': 1,  # 页码
        'size': 30,  # 数量
        'sort': "",  # 排序
        'uri': 'apidata/api/gkv3/special/lists'  # API接口
    }
    try:
        response = requests.post(url=url, data=url_data, headers=headers)
    except Exception as gk:
        print(gk)
        # 防反爬虫，停3秒再试
        time.sleep(3)
        response = requests.post(url=url, data=url_data, headers=headers)
    data = json.loads(response.text)['data']['item']
    info = {
        'name':  data[0]['name'],
        'special_id': data[0]['special_id'],
        'level1_name': data[0]['level1_name'],
        'level2_name': data[0]['level2_name'],
        'level3_name': data[0]['level3_name'],
        'limit_year': data[0]['limit_year']
    }
    print("专业: " + keyword + " 查询成功！")
    path = str(info['special_id']) + "_" + info['name'] + "_专业信息.json"
    save_json(path, info)
    return info


# 根据专业id查询指定专业的学校
# 测试：https://api.eol.cn/web/api/?is_single=2&local_province_id=42&local_type_id=2074&page=1&province_id=42&request_type=1&size=1000&special_id=990&top_school_id=707,3127&uri=apidata/api/gk/special/school&year=2021
def get_special_id_school(id, page=1):
    url = "https://api.eol.cn/web/api/"
    url_data = {
        'is_single': 2,
        'school_type': 6001,  # 6000 本科 6001 专科
        'local_province_id': province_id,  # 省份id
        'local_type_id': 2073,  # 物理类2073 历史类2074
        'page': page,  # 页码
        'province_id': province_id,  # 省份代码
        'request_type': 1,
        'size': 10,  # 查询数据
        'special_id': id,  # 990 专业id
        'uri': 'apidata/api/gk/special/school',  # api接口
        'year': 2021,  # 年
    }
    try:
        response = requests.post(url=url, data=url_data, headers=headers)
    except Exception as gk:
        print(gk)
        # 防反爬虫，停3秒再试
        time.sleep(3)
        response = requests.post(url=url, data=url_data, headers=headers)
    data = json.loads(response.text)['data']
    number = data['numFound']
    info = []
    for item in data['item']:
        info.append({
            'name': item['name'],
            'school_id': item['school_id'],
            'level_name': item['level_name'],
            'nature_name': item['nature_name'],
            'type_name': item['type_name'],
            'city_name': item['city_name'],
            'province_name': item['province_name'],
        })
    print("专业id: "+str(id)+",第"+str(page)+"页查找完成！")
    return number, info


# 指定学校的专业分数线
# 测试：https://static-data.gaokao.cn/www/2.0/schoolspecialindex/2020/1159/42/1/10/1.json  年/学校id/省id/1理科2文科/学科类型10专科/页码.json
def get_school_specialindex(id, page=1):
    url = "https://static-data.gaokao.cn/www/2.0/schoolspecialindex/2020/" + \
        str(id) + "/"+str(province_id)+"/2/10/"+str(page)+".json"
    try:
        response = requests.get(url=url, headers=headers)
    except Exception as gk:
        print(gk)
        # 防反爬虫，停3秒再试
        time.sleep(3)
        response = requests.get(url=url, headers=headers)
    data = json.loads(response.text)['data']
    number = data['numFound']
    info = []
    for item in data['item']:
        info.append({
            'spname': item['spname'],
            'school_id': item['school_id'],
            'special_id': item['special_id'],
            'min': item['min'],  # 最低分数
            'min_section': item['min_section'],  # 人数排名
            'level1_name': item['level1_name'],
            'level2_name': item['level2_name'],
            'level3_name': item['level3_name'],
            'local_batch_name': item['local_batch_name'],
            'zslx_name': item['zslx_name']
        })
    print("学校id: "+str(id)+",第"+str(page)+"页查找完成！")
    return number, info


# 指定学校的计划、学费
# 测试：https://static-data.gaokao.cn/www/2.0/schoolplanindex/2022/1159/42/2074/10/1.json  年/学校id/省id/2073物理类 2074生物类/学科类型/页码.json
def get_school_planindex(id, page=1):
    url = "https://static-data.gaokao.cn/www/2.0/schoolplanindex/2022/" + \
        str(id) + "/"+str(province_id)+"/2074/10/" + str(page) + ".json"
    try:
        response = requests.get(url=url, headers=headers)
    except Exception as gk:
        print(gk)
        # 防反爬虫，停3秒再试
        time.sleep(3)
        response = requests.get(url=url, headers=headers)
    data = json.loads(response.text)['data']
    number = data['numFound']
    info = []
    for item in data['item']:
        info.append({
            'spname': item['spname'],
            'school_id': item['school_id'],
            'special_id': item['special_id'],
            'length': item['length'],
            'tuition': item['tuition'],  # 学费
            'level1_name': item['level1_name'],
            'level2_name': item['level2_name'],
            'level3_name': item['level3_name'],
            'local_batch_name': item['local_batch_name'],
            'zslx_name': item['zslx_name']
        })
    print("学校id: "+str(id)+",第"+str(page)+"页查找完成！")
    return number, info


# 获取需要分页数据的所有数据
def get_all_page(id, page, func, **kwargs):
    file_name = {
        'get_special_id_school': "专业的所有学校",
        'get_school_specialindex': "学校专业分数线",
        'get_school_planindex': "学校招生计划"
    }
    path = str(id)+"_" + file_name[str(func.__name__)]+".json"
    # 判断文件是否存在
    if os.path.exists(path) == True:
        return read_json(path)
    number, info = func(id=id, page=page, **kwargs)
    # 一页10条数据，计算页数
    pages = math.ceil(number / 10)
    for i in range(pages - 1):
        n, f = func(id=id, page=i+2, **kwargs)
        info += f
    save_json(path, info)
    return info


# 指定学校id、指定专业的分数线和学费等
def get_all_school_id(id, special):
    # 获取学校专业分数线
    school_specialindex = get_all_page(id, 1, get_school_specialindex)
    search_special = [
        item for item in school_specialindex if special in item['spname']]
    # 获取学校学校的计划、学费
    school_planindex = get_all_page(id, 1, get_school_planindex)
    search_plan = [
        item for item in school_planindex if special in item['spname']]
    info = {}
    if search_special:
        info.update(search_special[0])
    else:
        info.update({
            'spname': '',
            'special_id': '',
            'min': 0,
            'min_section': 0,
            'level1_name': '',
            'level2_name': '',
            'level3_name': '',
            'local_batch_name': '',
            'zslx_name': ''
        })
    if search_plan:
        info.update(search_plan[0])
    else:
        info.update({
            'spname': '',
            'special_id': '',
            'length': '',
            'tuition': 0,
            'level1_name': '',
            'level2_name': '',
            'level3_name': '',
            'local_batch_name': '',
            'zslx_name': ''
        })
    return info


# 指定学校名称、指定专业获取分数线和学费等
def get_all_school_name(name, special):
    info = {}
    school = get_keyword_school(name)
    all_info = get_all_school_id(school['school_id'], special)
    info.update(school)
    info.update(all_info)
    return info


# 指定专业获取所有学校名称、指定专业获取分数线和学费等
def get_all(special_name):
    all_info = []
    special = get_keyword_special_id(special_name)
    school_all = get_all_page(special['special_id'], 1, get_special_id_school)
    for item in school_all:
        info = {}
        info.update(item)
        school_info = get_all_school_name(item['name'], special_name)
        info.update(school_info)
        all_info.append(info)
    path = str(special['special_id']) + "_" + special_name + ".json"
    save_json(path, all_info)
    return all_info


# 数据保存为json文件
def save_json(filename, data):
    with open(filename, 'w', encoding='utf8') as file_obj:
        file_obj.write(json.dumps(data, ensure_ascii=False))

 # 读取json文件内容,返回字典格式


def read_json(filename):
    with open(filename, 'r', encoding='utf8')as fp:
        json_data = json.load(fp)
        return json_data


if __name__ == "__main__":
    get_all("地理信息")
